package com.luych.oauth2Module.service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.luych.common.page.Page;
import com.luych.oauth2Module.entitey.Oauth2Client;
import com.luych.oauth2Module.entitey.Oauth2Scope;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

@Service
public class Oauth2ClientService {

    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;

    @Autowired
    public Oauth2ClientService(RestTemplate restTemplate, ObjectMapper objectMapper) {
        this.restTemplate = restTemplate;
        this.objectMapper = objectMapper;
    }


    public Page pageClient(String keywords, Page page) throws IOException, InvocationTargetException, IllegalAccessException {
        String response = restTemplate.getForObject(
                "http://OAUTH2CENTER/oauth2/client" +
                        "?keywords={1}&pageNumber={2}&pageSize={3}&sortName={4}&sortOrder={5}", String.class,
                keywords, page.getPageNumber(), page.getPageSize(), page.getSortName(), page.getSortOrder());
        page = objectMapper.readValue(response, new TypeReference<Page>(){});
        List<Oauth2Client> oauth2Clients = new ArrayList<>(page.getRecords().size());
        for (Object o : page.getRecords()) {
            Map record = (LinkedHashMap) o;
            Oauth2Client oauth2Client = new Oauth2Client();
            BeanUtils.populate(oauth2Client, record);
            oauth2Clients.add(oauth2Client);
        }
        page.setRecords(oauth2Clients);
        return page;
    }

    public void removeClient(String clientId) {
        restTemplate.delete("http://OAUTH2CENTER/oauth2/client/{clientId}", clientId);
    }

    public Oauth2Client modifyClient(Oauth2Client oauth2Client) {
        return restTemplate.postForObject("http://OAUTH2CENTER/oauth2/client/{clientId}", oauth2Client, Oauth2Client.class, oauth2Client.getClientId());
    }

    public Oauth2Client addClient(Oauth2Client oauth2Client) {
        ResponseEntity<Oauth2Client> responseEntity = restTemplate.exchange("http://OAUTH2CENTER/oauth2/client", HttpMethod.PUT, new HttpEntity<>(oauth2Client), Oauth2Client.class);
        if (!responseEntity.getStatusCode().equals(HttpStatus.OK)) {
            throw new RestClientException("[" + responseEntity.getStatusCodeValue() + "]" + responseEntity.getStatusCode().getReasonPhrase());
        }
        return  responseEntity.getBody();
    }

    public List<Oauth2Scope> getScopeByClientId(String clientId) throws IOException {
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, Oauth2Scope.class);
        String response = restTemplate.getForObject("http://OAUTH2CENTER/oauth2/scope/{clientId}", String.class, clientId);
        return response == null ? null : objectMapper.readValue(response, javaType);
    }

    public Oauth2Client getByClientId(String clientId) {
        return restTemplate.getForObject("http://OAUTH2CENTER/oauth2/client/{clientId}", Oauth2Client.class, clientId);
    }
}
